/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package lifecraft;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

class Chunk {
    List<Block> Blocks = new ArrayList<Block>();
    public boolean update_need;
    World worldRef;
    
    int x,y;
    
    public Chunk left;
    public Chunk right;
    public Chunk down;
    public Chunk up;
    void reset(){
        Blocks.clear();
        create();
    }
    
    boolean pump(Block b, int index){
        update_need=true;
        
        if(index%27==26){ //z góry
            
            if(Blocks.get(index-1).GetType()==0 || (Blocks.get(index-1).GetID()==SurfC.WATER && Blocks.get(index-1).Set(0, 0)!=32)){
                Blocks.set(index, b);
                return true;
            }
            
        }else if(index<27){ //z lewej
            if((Blocks.get(index+27).GetType()==0 && b.Set(0, 0)>1)||(Blocks.get(index+27).GetID()==SurfC.WATER && Blocks.get(index+27).Set(0,0)<b.Set(0, 0)))
            {
                Blocks.set(index, b);
                return true;
            }
            
        }else if(index>999-27){ //z prawej
            if((Blocks.get(index-27).GetType()==0 && b.Set(0, 0)>1)||(Blocks.get(index-27).GetID()==SurfC.WATER && Blocks.get(index-27).Set(0,0)<b.Set(0, 0)))
            {
                Blocks.set(index, b);
                return true;
            }
            
        }
        return false;
    }
    void create(){
        x=0;
        y=0;
        Random rand = new Random();
        int sky_height = 10;
        for(int i=0;i<37;i++){
            sky_height+= rand.nextInt(3)-1;
            if(sky_height<=4) sky_height++;
            if(sky_height>=25) sky_height--;
            
            for(int j=0;j<27;j++){
                if(i==0||i==36||j==0||j==26){
                    Blocks.add(new Air(i,j,SurfC.AIR));
                }else {
                    if(j>sky_height){
                        Blocks.add(new Air(i,j,SurfC.AIR));
                        continue;
                    }                
                
                    if(j==sky_height){
                        Blocks.add(new Air(i,j,SurfC.GRASS));
                    } else{
                        Blocks.add(new Solid(i,j,SurfC.DIRT));
                    }
                }
            }
        }        
        
        for(int k=0;k<35;k++)
        {
            int i=k+1;
            for(int l=0;l<25;l++)
            {   
                int j=l+1;
                int IfLake=rand.nextInt(80);
                if(IfLake==0) {
                    if(Blocks.get(i*27+j).GetID()!=SurfC.AIR){
                        Blocks.set(i*27+j, new Liquid(i,j,SurfC.WATER,32));
                            
                            if(j>0)
                                Blocks.set(i*27+j-1, new Liquid(i,j-1,SurfC.WATER,32));
                            if(i<34)
                                Blocks.set((i+1)*27+j, new Liquid(i+1,j,SurfC.WATER,32));
                            if(i>0)
                                Blocks.set((i-1)*27+j, new Liquid(i-1,j,SurfC.WATER,32));
                            if(j<24)
                                Blocks.set(i*27+j+1, new Liquid(i,j+1,SurfC.WATER,32));
                            
                    }
                }
            }
        }
        update_need=true;
    }
    void Draw(int x, int y,  boolean pause)
    {
        x-=32; y-=32;
        int k,l;
        for(int i=0;i<35;i++){
            k=i+1;
            for(int j=0;j<25;j++){
                l=j+1;
                Blocks.get(k*27+l).Draw(x+this.x, y+this.y);
            }
        }      
        if (pause) update_need=false; //potrzebne po to aby gdy zatrzymuje czas nic sie nie zmienialo!    
        
        if(update_need){
            update_need=Update();           
        }
             
    }
    boolean Update(){
        boolean updated=false;
        for(int i=0;i<999;i++){
            switch(Blocks.get(i).Update()){                
                case 1:
                    updated=(spill(Blocks.get(i), i )?true:updated);
                case 0:
                    if(Blocks.get(i).GetID()==SurfC.GRASS)
                        grassCheck(Blocks.get(i));
                    break;          
                }
        }
        return updated;
    }
    boolean grassCheck(Block B){
        boolean updated = false;
        int  B_index, orgB_index;
        orgB_index=B_index=B.GetIndex();
        
        if(B_index<999) {
                   
            B_index--;
            if(Blocks.get(B_index).GetID()!=SurfC.DIRT && B_index>=0){
                    
              //  if(Blocks.get(B_index).GetType()==0 )
                        Blocks.set(orgB_index, new Air( orgB_index/27 , (orgB_index%27) , SurfC.AIR ));
            }
                     
            B_index+=2;
            
                if(Blocks.get(B_index).GetID()!=SurfC.AIR && B_index<875){
                    
                //if(Blocks.get(B_index).GetType()==0 )
                        Blocks.set(orgB_index, new Air( orgB_index/27 , (orgB_index%27) , SurfC.AIR ));
                 
            }
            }
        
        return false;
    }
    
    public boolean spill(Block B, int i){
        boolean updated = false;
        int  B_index, orgB_index;
        orgB_index=B_index=i;
        
        if(B_index<999 && B_index%27!=0) {
                   
            B_index--;
            if(B_index%27!=0){
                if(B_index<999-27&&B_index>27){
                if(Blocks.get(B_index).GetType()==0 ){
                        B.Set(-1,0);
                        Blocks.set(B_index, new Liquid( B_index/27 , (B_index%27) , SurfC.WATER ,1 ));
                        updated=true;
                } else if(Blocks.get(B_index).GetID()==SurfC.WATER && Blocks.get(B_index).Set(0, 0)!=32){
                        B.Set(-1,0);
                        Blocks.get(B_index).Set(1, 0); 
                        updated=true;
                } 
                }
            }else {
                
                if(down!=null){
                    if(down.pump(B, B_index+26)){
                        update_need=true;
                        B.Set(-1, 0);
                    }
                }

            }
            
            if(B.Set(0, 0)<=0)
                Blocks.set(orgB_index, new Air(orgB_index/27,(orgB_index%27),SurfC.AIR));
                     
            B_index+=28;
            
            if(B_index<999-27){
                if(Blocks.get(B_index).GetType()==0 && B.Set(0, 0)>1){
                    B.Set(-1,0);
                    Blocks.set(B_index, new Liquid( B_index/27 , (B_index%27) , SurfC.WATER ,1 ));
                    updated=true;
                } else if(Blocks.get(B_index).GetID()==SurfC.WATER && Blocks.get(B_index).Set(0,0) < B.Set(0, 0)) {
                    B.Set(-1,0);
                    Blocks.get(B_index).Set(1, 0); 
                    if(Blocks.get(B_index).Set(0,0)<B.Set(0, 0))
                          updated=true;
                } 
            }
            else {
                if(right!=null){
                    if(right.pump(B,B_index-972)){
                        update_need=true;
                        //B.Set(-1,0);
                    }
                }
            }
            if(B.Set(0, 0)<=0)
                Blocks.set(orgB_index, new Air(orgB_index/27,(orgB_index%27),SurfC.AIR));
                B_index-=54;
            if(B_index>=27)
            {
                    
                if(Blocks.get(B_index).GetType()==0 && B.Set(0, 0)>1){
                    B.Set(-1,0);
                    Blocks.set(B_index, new Liquid( B_index/27 , (B_index%27) , SurfC.WATER ,1 ));
                    updated=true;
                } else if(Blocks.get(B_index).GetID()==SurfC.WATER && Blocks.get(B_index).Set(0,0)<B.Set(0, 0)){
                    B.Set(-1,0);
                    Blocks.get(B_index).Set(1, 0);   
                    if(Blocks.get(B_index).Set(0,0)<B.Set(0, 0))
                            updated=true;
                } 
            }
            else{
                if(left!=null){
                    if(left.pump(B, B_index+972)){
                        update_need=true;                    
                    }
                }
            }
            if(B.Set(0, 0)<=0)
                Blocks.set(orgB_index, new Air(orgB_index/27,(orgB_index%27),SurfC.AIR));
        }
        return updated;
    }
    void insertAt (int x, int y, SurfC ID)
    {
        x+=32; y+=32;
        x-=this.x; y-=this.y;
        if((ID.ID>=1)&&(ID.ID<100)) Blocks.set(x/32*27+y/32, new Air(x/32, y/32, ID)); 
        else if((ID.ID>=100)&&(ID.ID<200)) Blocks.set(x/32*27+y/32, new Solid(x/32, y/32, ID)); 
        else if((ID.ID>=200)&&(ID.ID<300)) Blocks.set(x/32*27+y/32, new Liquid(x/32, y/32, ID, 32)); 
            
        update_need=true;
    }
    void destroyAt(int x, int y)
    {
        x+=32; y+=32;
        x-=this.x; y-=this.y;
        Blocks.set(x/32*27+y/32, new Air(x/32, y/32, SurfC.AIR));      
        update_need=true;
    }
}
